import { Executor, RejectType, ResolveType, StatusEnum } from "./actiontype";

export default class Promise<T = any> {
  public resolve!: ResolveType;
  public reject!: RejectType;
  public status!: StatusEnum;
  public resolve_executor_value!: any;
  public reject_executor_value!: any;
  // 保存成功状态要执行的函数
  public resolve_then_callback: (() => void)[] = [];
  // 保存失败状态要执行的函数
  public reject_then_callback: (() => void)[] = [];

  constructor(executor: Executor) {
    this.status = StatusEnum.PENDING;

    this.resolve = (successValue: any): any => {
      // 状态凝固
      if (this.status === StatusEnum.PENDING) {
        console.log("进入到resolve方法");
        this.status = StatusEnum.SUCCESS;
        this.resolve_executor_value = successValue;

        this.resolve_then_callback.forEach((callback) => callback());
      }
    };

    this.reject = (failValue: any): any => {
      // 状态凝固
      if (this.status === StatusEnum.PENDING) {
        this.status = StatusEnum.FAIL;
        this.reject_executor_value = failValue;
      }
    };

    try {
      // 执行函数
      executor(this.resolve, this.reject);
    } catch (error: any) {
      // 失败直接执行reject函数
      this.status = StatusEnum.PENDING;
      this.reject(error.toString());
      throw new Error("程序终止");
    }
  }

  then(resolveInThen: ResolveType, rejectInThen: RejectType) {
    return new Promise((resolve, reject) => {
      let result: any;
      console.log("this:", this);
      if (this.status === StatusEnum.SUCCESS) {
        result = resolveInThen(this.resolve_executor_value);

        if (isPromise(result)) {
          setTimeout(() => {
            resolve(result.resolve_executor_value);
          }, 5);
        } else {
          resolve(result);
        }
      }

      if (this.status === StatusEnum.FAIL) {
        result = rejectInThen(this.reject_executor_value);
        reject(result);
      }

      if (this.status === StatusEnum.PENDING) {
        this.resolve_then_callback.push(() => {
          result = resolveInThen(this.resolve_executor_value);
          console.log("then中resolve函数参数执行的结果：", result);
          resolve(result);
        });

        this.reject_then_callback.push(() => {
          result = rejectInThen(this.reject_executor_value);
          console.log("then中reject函数参数执行的结果：", result);
        });
      }
    });
  }
}

function isPromise(val: any): val is Promise {
  return isObject(val) && isFunction(val);
}

function isObject(val: any): val is Record<any, any> {
  return val !== null && typeof val === "object";
}

function isFunction(data: any): data is Function {
  return typeof data === "function";
}

export {};
